﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace grounding.parser.Parsers
{
    public enum LabelType
    {
        //None = 0,
        Awake = 1,
        Tired = -1,
        Balancing = 2,
        Falling = -2,
        Carried = 3,
        NotCarried = -3,
        Cold = 4,
        Hot = -4,
        //DarkRoom = 5,
        //LightRoom = -5,
        //LookAtFace = 6,
        //LookAtObject = -6,
        HeavyWeight = 7,
        LightWeight = -7,
        Moving = 8,
        Stationary = -8,
        Near = 9,
        Far = -9,
        //Affection = 10
    }

    public class Label : ILogicElement
    {
        #region Static

        static protected Dictionary<LabelType, Label> labels = new Dictionary<LabelType, Label>()
        {
            { LabelType.Awake, new Label(LabelType.Awake, "awake") },
            { LabelType.Tired, new Label(LabelType.Tired, "tired") },
            { LabelType.Balancing, new Label(LabelType.Balancing, "balancing") },
            { LabelType.Falling, new Label(LabelType.Falling, "falling") },
            { LabelType.Carried, new Label(LabelType.Carried, "being carried") },
            { LabelType.NotCarried, new Label(LabelType.NotCarried, "not being carried") },
            { LabelType.Cold, new Label(LabelType.Cold, "cold") },
            { LabelType.Hot, new Label(LabelType.Hot, "hot") },
            //{ LabelType.DarkRoom, new Label(LabelType.DarkRoom, "in a dark room") },
            //{ LabelType.LightRoom, new Label(LabelType.LightRoom, "in a light room") },
            //{ LabelType.LookAtFace, new Label(LabelType.LookAtFace, "looking at a face") },
            //{ LabelType.LookAtObject, new Label(LabelType.LookAtObject, "looking at an object") },
            { LabelType.HeavyWeight, new Label(LabelType.HeavyWeight, "holding something heavy") },
            { LabelType.LightWeight, new Label(LabelType.LightWeight, "holding something light") },
            { LabelType.Moving, new Label(LabelType.Moving, "moving") },
            { LabelType.Stationary, new Label(LabelType.Stationary, "stationary") },
            { LabelType.Near, new Label(LabelType.Near, "near") },
            { LabelType.Far, new Label(LabelType.Far, "far") },
            //{ LabelType.Affection, new Label(LabelType.Affection, "appreciated") }
        };

        static public Label[] Labels { get { return labels.Values.ToArray(); } }

        static public Label GetLabel(LabelType type) { return labels[type]; }
        static public Label GetLabel(int identifier) { return labels[(LabelType)identifier]; }
        static public Label GetLabel(Category category, int label) {
            return labels[(LabelType)(category.Identifier * label)];
        }
        static public Label GetLabel(string name)
        {
            LabelType type;
            if (!Enum.TryParse<LabelType>(name, true, out type))
                throw new ArgumentException(
                    string.Format("String \"{0}\" could not be parsed into as a LabelType", name));
            return labels[type];
        }

        #endregion

        public LabelType Type { get; set; }
        public string PrettyDescription { get; set; }

        public int NormalizedIdentifier { get { return Math.Sign((int)Type); } }

        public Category Parent { get { return Category.GetCategory(Math.Abs((int)Type)); } }

        public Label(LabelType type, string prettyDescription) {
            Type = type;
            PrettyDescription = prettyDescription;
        }




        #region ILogicElement Members

        /// <summary>
        /// Gets the name of the label
        /// </summary>
        public string Element { get { return Type.ToString().ToLower(); } }

        public int Identifier { get { return (int)Type; } }

        #endregion

        public override string ToString() { return Element; }
    }
}
